package com.alibaba.citrus.cr.unified.inventory.facade.service;

import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.lock.RedisLock;
import com.alibaba.citrus.cr.unified.inventory.contants.FeaturesKey;
import com.alibaba.citrus.cr.unified.inventory.functions.factory.AllocateOrderEntityFactory;
import com.alibaba.citrus.cr.unified.inventory.functions.service.AllocateOrderCloseService;
import com.alibaba.citrus.cr.unified.inventory.handler.FulfillmentOrderOpenApi;
import com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntity;
import com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntityComposeRequest;
import com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderSapSyncMessageEntity;
import com.alibaba.citrus.cr.unified.inventory.model.TransferOrderCloseDetail;
import com.alibaba.citrus.cr.unified.inventory.model.TransferOrderCloseRequest;
import com.alibaba.citrus.cr.unified.inventory.model.TransferOrderCloseResponse;
import com.alibaba.citrus.cr.unified.inventory.utils.CompareUtil;
import com.alibaba.citrus.cr.unified.inventory.utils.InfoUtil;
import com.alibaba.citrus.cr.unified.inventory.utils.ToolUtil;
import com.alibaba.cloud.retail.delivery.api.model.delivery.enums.FulfillmentDirectionTypeEnum;
import com.alibaba.cloud.retail.delivery.api.model.delivery.enums.FulfillmentOrderStatusEnum;
import com.alibaba.cloud.retail.delivery.api.model.delivery.enums.FulfillmentTypeEnum;
import com.alibaba.cloud.retail.delivery.api.model.delivery.enums.OrderTypeEnum;
import com.alibaba.cloud.retail.delivery.api.model.delivery.request.fulfillment.CreateFulfillmentOrderDetailDTO;
import com.alibaba.cloud.retail.delivery.api.model.delivery.request.fulfillment.CreateFulfillmentOrderReq;
import com.alibaba.cloud.retail.delivery.api.model.delivery.request.fulfillment.FinishReq;
import com.alibaba.cloud.retail.delivery.api.model.delivery.request.fulfillment.UpdateFulfillmentOrderDetailFeaturesReq;
import com.alibaba.cloud.retail.delivery.api.model.delivery.request.fulfillment.UpdateFulfillmentOrderFeaturesReq;
import com.alibaba.cloud.retail.delivery.api.model.delivery.response.fulfillment.BatchCloseFulfillmentOrderResponse;
import com.alibaba.cloud.retail.delivery.api.model.delivery.response.fulfillment.FulfillmentDetailGetRes;
import com.alibaba.cloud.retail.delivery.api.model.delivery.response.fulfillment.FulfillmentGetRes;
import com.alibaba.cloud.retail.delivery.api.model.delivery.response.fulfillment.FulfillmentOrderResponse;
import com.alibaba.cloud.retail.delivery.api.model.fulfillment.request.SearchFulfullmentOrderReq;
import com.alibaba.cloud.retail.delivery.api.service.bcfulfillment.FulfillmentOrderAbilityService;
import com.alibaba.cloud.retail.store.api.service.CargoZoneQueryService;
import com.alibaba.cloud.retail.store.request.cargozone.QueryCargoZoneRequest;
import com.alibaba.cloud.retail.store.response.ResultPager;
import com.alibaba.cloud.retail.wms.api.model.orders.common.WarehousingOrderDTO;
import com.alibaba.cloud.retail.wms.api.model.orders.common.WmsOrderDetailDTO;
import com.alibaba.cloud.retail.wms.api.model.orders.request.WmsOrderQueryRequest;
import com.alibaba.cloud.retail.wms.api.model.orders.response.WarehousingOrdersQueryResponse;
import com.alibaba.cloud.retail.wms.api.service.orders.WarehousingOrderReadService;
import com.alibaba.cz.base.model.store.CargoZoneSDO;
import com.alibaba.cz.base.tool.DateFormatUtil;
import com.alibaba.cz.base.tool.FeatureUtil;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.contants.BcOrderConstants;
import com.epoch.app.crunifiedinventory.allocateorderdomain.dto.UpdateStatusRequest;
import com.epoch.app.crunifiedinventory.allocateorderdomain.service.AllocateOrderDomainService;
import com.epoch.app.crunifiedinventory.allocateordersapsyncmessage.dto.SapSyncRequest;
import com.epoch.app.crunifiedinventory.allocateordersapsyncmessage.service.AllocateOrderSapSyncMessageService;
import com.epoch.app.crunifiedinventory.domain.allocateorder.dto.LoadAllocateOrderRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorder.model.AllocateOrder;
import com.epoch.app.crunifiedinventory.domain.allocateorder.service.AllocateOrderService;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.UpdateFeaturesRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.model.AllocateOrderDetail;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.service.AllocateOrderDetailService;
import com.epoch.app.crunifiedinventory.dto.request.AllocateOrderSyncRequest;
import com.epoch.app.crunifiedinventory.model.dto.AllocateOrderScItemDetailDTO;
import com.epoch.app.crunifiedinventory.model.enums.AllocateOrderStatus;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: yuhw
 * @date: 2024年03月07日 16:51
 **/
@Primary
@Service
public class AllocateOrderSapSyncMessageServiceImpl implements AllocateOrderSapSyncMessageService {
    private static Log log = Log.getLogger(AllocateOrderSapSyncMessageServiceImpl.class);

    @DubboReference
    private FulfillmentOrderAbilityService fulfillmentOrderAbilityService;
    @DubboReference
    private CargoZoneQueryService cargoZoneQueryService;
    @DubboReference
    private WarehousingOrderReadService warehousingOrderReadService;
    @Resource
    private AllocateOrderService allocateOrderService;
    @Resource
    private AllocateOrderCloseService allocateOrderCloseService;
    @Resource
    private AllocateOrderDetailService allocateOrderDetailService;
    @Resource
    private FulfillmentOrderOpenApi fulfillmentOrderOpenApi;
    @Resource
    private AllocateOrderEntityFactory allocateOrderEntityFactory;
    @Resource
    private AllocateOrderDomainService allocateOrderDomainService;

    private static final String SAP_SYNC_LOCK = "SAP_SYNC_LOCK";

    @Override
    @FacadeInvoker
    public Result<String> sapSync(SapSyncRequest sapSyncRequest) {
//        log.info("AllocateOrderSapSyncMessageServiceImpl_sapSync_request:{}",JSON.toJSONString(sapSyncRequest));
        AllocateOrderSapSyncMessageEntity messageEntity = JSON.parseObject(sapSyncRequest.getMessage(),AllocateOrderSapSyncMessageEntity.class);
        if (messageEntity != null && messageEntity.getCurrent() != null && messageEntity.getSyncRequest() != null){
            log.info("AllocateOrderSapSyncMessageServiceImpl_sapSync_entity:{}",JSON.toJSONString(messageEntity));
            try(RedisLock lock = new RedisLock(BcOrderConstants.REDIS_CACHE_CODE(),SAP_SYNC_LOCK + messageEntity.getSyncRequest().getOutAllocateOrderId(),5 * 60 * 1000,10 * 60 * 1000)){
                if (!lock.lock()){
                    throw new FacadeException("OTS-03-005-00-15-096");
                }
                handleFulfillmentOrder(messageEntity.getOrigin(),messageEntity.getCurrent(),messageEntity.getSyncRequest());
                if (Nullable.stream(messageEntity.getCurrent().getDetailList()).anyMatch(detail -> Boolean.TRUE.equals(detail.getClose()))) {
                    UpdateStatusRequest updateStatusRequest = UpdateStatusRequest.builder().code(messageEntity.getCurrent().getAllocateOrder().getCode()).build();
                    allocateOrderDomainService.updateStatus(updateStatusRequest);
                }
                AllocateOrderEntityComposeRequest composeRequest = AllocateOrderEntityComposeRequest.builder().outAllocateOrderId(messageEntity.getSyncRequest().getOutAllocateOrderId()).build();
                AllocateOrderEntity allocateOrderEntity = allocateOrderEntityFactory.composeAllocateOrderEntity(composeRequest);
                log.info("sapSync_allocateOrderEntity:{}",JSON.toJSONString(allocateOrderEntity));
            }
        }
        return Result.success(System.currentTimeMillis() +"");
    }

    /** 008回复时, 根据确认数量变化 创建履约单 **/
    /**
     * SAP调拨单数量修改时，中台调拨单数量跟着一起修改，无其他逻辑。
     * SAP确认数量修改时，跟中台调拨单确认数量进行比较：
     * 若SAP>中台，则根据差值，创建新的履约单
     * 若SAP<中台，查询调拨单所关联的所有履约单所关联的所有出库单明细1：
     * 修改后的总确认数量<所有出库单明细1，不处理（SAP会控制一定不会小于当前的出库单明细1即交货单数量）
     * 修改后的总确认数量>=所有出库单明细1，对比每一个履约单与其对应的所有出库单明细1，（当前的目标是要将总的履约单数量修改为【修改后的总确认数量】，计算一下当前的【差值】）
     * 履约单数量<=所有出库单明细1，不处理（不可能小）
     * 履约单数量>所有出库单明细1，将这些履约单按照创建时间倒序排列，在总差值的范围内，向下修改履约单的数量（不能低于明细1数量）。
     * 如果都处理成功了，则修改调拨单上的确认数量，如果失败，则不修改调拨单上的确认数量（记录错误原因）
     * 调拨单数量和确认数量的修改解耦，彼此互不相关。
     * @param origin 008更新前的调拨单明细
     * @param current 008更新后的调拨单明细
     * @param syncRequest 008更新请求入参
     */
    public void handleFulfillmentOrder(com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntity origin,
                                       com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntity current,
                                       AllocateOrderSyncRequest syncRequest){
        if (current == null || current.getAllocateOrder() == null || CollectionUtils.isEmpty(current.getDetailList())){
            log.info("handleFulfillmentOrder_pass");
            return;
        }
        // 是否要剔除关闭标记的明细
        createFulfillmentOrder(origin,current,syncRequest);
        try{
            closeFulfillmentOrderAndAllocateOrder(origin,current);
        }catch (Throwable e){
            log.error("AllocateOrderWriteServiceImpl_close_error",e);
        }
        try {
            closeToOpen(origin,current);
        }catch (Throwable e){
            log.info("AllocateOrderWriteServiceImpl_closeToOpen_error",e);
        }
        //构建正向履约单的主单和明细
    }

    /**
     * 创建履约单(正向)
     * @param origin
     * @param current
     */
    private void createFulfillmentOrder(com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntity origin,
                                        com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntity current,
                                        AllocateOrderSyncRequest syncRequest){
        AllocateOrder currentAllocateOrder = current.getAllocateOrder();
        // 判断下 是否自动履约履约 且 是否是大厂履约
        /**
         * 008回复时能否创建履约单(无论正逆向)
         * F-F1 计划调拨 不创
         * F-F1 计划货场 不创
         * 货场提货  创 正向
         *
         *仓间调拨
         *  试点-试点  创 正向
         *  试点-外部  创 正向
         *  外部-试点 sap 创  不创
         *
         * 退单
         * F-F1 计划退单, 008创建 创调拨退单出库的; 正向
         * 仓间
         * 外部到-试点, 退单,  SAP创,  008创建 调拨退单出库 正向,
         * 试点-外部 退单  sap创, 008不能创, 等出库创逆向, 调拨退单入库.
         * 试点-试点, 退单 008创建调拨退单出库., 正向.
         */
        if (!Boolean.TRUE.equals(currentAllocateOrder.getAutoFulfillment()) ||
                Arrays.asList(com.epoch.app.crunifiedinventory.model.enums.FulfillmentTypeEnum.PILOT2CURRENT,
                                com.epoch.app.crunifiedinventory.model.enums.FulfillmentTypeEnum.PILOT2PILOT,
                                com.epoch.app.crunifiedinventory.model.enums.FulfillmentTypeEnum.VIRTUAL_TRANSFER).stream()
                        .noneMatch(fulfillmentTypeEnum -> fulfillmentTypeEnum.getValue().toString().equals(currentAllocateOrder.getFulfillmentTypeCode()))){
            log.info("no_need_create_forward_fulfillment_order:{}",JSON.toJSONString(current));
            return;
        }
        boolean isCreate = Objects.isNull(origin);
        //判断是否是新建, 注意要筛选出是确认数量
        if (isCreate){
            log.info("createFulfillmentOrder_isCreate");
            Map<String, String> bizFeaturesMap = FeatureUtil.fromString(currentAllocateOrder.getBizFeatures());
            createForwardOrder(currentAllocateOrder,current.getDetailList(),bizFeaturesMap);
        }else {
            log.info("createFulfillmentOrder_isUpdate");
            //生成一个关闭履约单的请求
            List<FinishReq.FulfillmentOrderInfo> finishDetailList = Lists.newArrayList();
            //关闭履约单后, 又需要创建的履约单子明细
            List<CreateFulfillmentOrderDetailDTO> createFulfillmentOrderDetailDTOList = Lists.newArrayList();
            //更新数量时 需要关闭的
            List<AllocateOrderDetail> updateCloseDetailList = Lists.newArrayList();
            //提前查一下调拨单的正向履约单明细
            List<FulfillmentGetRes> fulfillmentGetResList = searchFulfillmentOrder(currentAllocateOrder.getCode(), FulfillmentDirectionTypeEnum.FORWARD.getValue());
            List<CreateFulfillmentOrderDetailDTO> detailDTOList = buildCreateFulfillmentOrderDetailDTOList(origin.getDetailList(), current.getDetailList(), currentAllocateOrder, syncRequest,finishDetailList,createFulfillmentOrderDetailDTOList,fulfillmentGetResList,updateCloseDetailList);
            //确认数量小的情况
            if (CollectionUtils.isNotEmpty(finishDetailList)){
                //需要关闭
                FinishReq finishReq = new FinishReq();
                finishReq.setBusinessType(currentAllocateOrder.getBusinessType());
                finishReq.setFromSys(currentAllocateOrder.getFromSys());
                //TODO 是否是一直6000
                finishReq.setBusinessUnitCode("6000");
                finishReq.setUpdater("system");
                finishReq.setFulfillmentOrderInfoList(finishDetailList);
                log.info("update_finish_request:{}",JSON.toJSONString(finishReq));
                com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result<List<BatchCloseFulfillmentOrderResponse>> finish = fulfillmentOrderAbilityService.finish(finishReq);
                log.info("update_finish_result:{}",JSON.toJSONString(finish));
                if (finish != null && CollectionUtils.isNotEmpty(finish.getResult())){
                    //TODO 有失败的
                    boolean hasFail = finish.getResult().stream().anyMatch(b -> StringUtils.isNotBlank(b.getErrorCode()));
                    //记录错误信息
                    finish.getResult().forEach(r -> {
                        //履约单关闭的行报错了, 那就要回写错误信息;
                        //找到调拨单 TODO 履约单有些场景100 100 就不能关
                        List<BatchCloseFulfillmentOrderResponse> failCloseResponses = finish.getResult().stream().filter(b -> StringUtils.isNotBlank(b.getErrorCode())).collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(failCloseResponses)){
                            //找到到底是调拨单的哪几行失败了.
                            //key 行号, value原因
                            Map<String,String> errorMap = Maps.newHashMap();
                            failCloseResponses.forEach(f -> {
                                //找到调拨单的行号
                                String allocateOrderLineNo = fulfillmentGetResList.stream().filter(res -> f.getFulfillmentOrderNo().equals(res.getFulfillmentOrderNo()))
                                        .map(FulfillmentGetRes::getDetailList).filter(CollectionUtils::isNotEmpty).flatMap(Collection::stream)
                                        .filter(fulfillmentDetailGetRes -> fulfillmentDetailGetRes.getLineNumber().toString().equals(f.getFulfillmentSubOrderNo()))
                                        .map(FulfillmentDetailGetRes::getRefOrderLineNo).findFirst().orElse(null);
                                if (errorMap.containsKey(allocateOrderLineNo)){
                                    return;
                                }
                                errorMap.put(allocateOrderLineNo,f.getMessage());
                            });
                            if (MapUtils.isNotEmpty(errorMap)){
                                errorMap.forEach((k,v) ->{
                                    AllocateOrderDetail errorDetail = current.getDetailList().stream().filter(detail -> Objects.equals(detail.getLineNo() == null ? null : detail.getLineNo().toString(), k))
                                            .findFirst().orElse(null);
                                    if (errorDetail == null){
                                        return;
                                    }
                                    UpdateFeaturesRequest updateFeaturesRequest = new UpdateFeaturesRequest();
                                    updateFeaturesRequest.setLineNo(k);
                                    updateFeaturesRequest.setMainOrderCode(errorDetail.getAllocateOrderCode());
                                    Map<String, String> bizFeatures = FeatureUtil.fromString(errorDetail.getBizFeatures());
                                    bizFeatures.put(FeaturesKey.FULFILLMENT_CLOSE_FAIL_MSG,v);
                                    updateFeaturesRequest.setBizFeatures(FeatureUtil.toString(bizFeatures));
                                    allocateOrderDetailService.updateFeatures(updateFeaturesRequest);
                                });
                            }
                        }
                    });

                }
                //关闭的结果不影响 再重新创建 TODO 失败了,有些场景不能继续走
                if (CollectionUtils.isNotEmpty(createFulfillmentOrderDetailDTOList)){
                    CreateFulfillmentOrderReq req = buildCreateFulfillmentOrderReq(currentAllocateOrder);
                    req.setDetailList(createFulfillmentOrderDetailDTOList);
                    com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result<FulfillmentOrderResponse> order;
                    log.info("update_createFulfillmentOrder_request:{}",JSON.toJSONString(req));
                    if (FulfillmentTypeEnum.EXTERNALWAREHOUSE_FULFILLMENT.getValue().equals(req.getFulfillmentType())){
                        order = fulfillmentOrderAbilityService.createSalesOrderForExternalWarehouse(req);
                    }else {
                        order = fulfillmentOrderOpenApi.createOrder(req);
                    }
                    log.info("update_createFulfillmentOrder_result:{}",JSON.toJSONString(order));
                    UpdateFulfillmentOrderFeaturesReq featuresReq = buildUpdateFulfillmentOrderFeaturesReq(req, order.getResult());
                    log.info("updateFulfillmentOrderFeatures_request:{}",JSON.toJSONString(featuresReq));
                    com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result updateFeatures = fulfillmentOrderAbilityService.updateFulfillmentOrderFeatures(featuresReq);
                    log.info("updateFulfillmentOrderFeatures_result:{}",JSON.toJSONString(updateFeatures));
                }
            }

            if (CollectionUtils.isEmpty(detailDTOList)){
                log.info("buildCreateFulfillmentOrderDetailDTOList_is_empty");
                return;
            }
            CreateFulfillmentOrderReq req = buildCreateFulfillmentOrderReq(currentAllocateOrder);
            req.setDetailList(detailDTOList);
            log.info("syncAllocateOrder_create_order_request:{}",JSON.toJSONString(req));
            com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result<FulfillmentOrderResponse> order;
            if (FulfillmentTypeEnum.EXTERNALWAREHOUSE_FULFILLMENT.getValue().equals(req.getFulfillmentType())){
                order = fulfillmentOrderAbilityService.createSalesOrderForExternalWarehouse(req);
            }else {
                order = fulfillmentOrderOpenApi.createOrder(req);
            }
            log.info("syncAllocateOrder_create_order_response:{}",JSON.toJSONString(order));
            if (order != null && order.isSuccess()){
                UpdateFulfillmentOrderFeaturesReq featuresReq = this.buildUpdateFulfillmentOrderFeaturesReq(req, order.getResult());
                log.info("updateFulfillmentOrderFeatures_request:{}",JSON.toJSONString(featuresReq));
                com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result  updateFulfillmentOrderFeatures = fulfillmentOrderAbilityService.updateFulfillmentOrderFeatures(featuresReq);
                log.info("updateFulfillmentOrderFeatures_result:{}",JSON.toJSONString(updateFulfillmentOrderFeatures));
                //履约单号放入features
                AllocateOrder allocateOrder = allocateOrderService.loadAllocateOrder(LoadAllocateOrderRequest.builder().id(currentAllocateOrder.getId().toString()).build());
                if (allocateOrder != null){
                    Map<String, String> featuresMap = FeatureUtil.fromString(currentAllocateOrder.getFeatures());
//                Map<String, String> bizFeaturesMap = FeatureUtil.fromString(currentAllocateOrder.getBizFeatures());
                    String fulfillmentNo = Optional.ofNullable(order).map(com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result::getResult)
                            .map(FulfillmentOrderResponse::getFulfillmentOrderNo).orElse(null);
                    if (StringUtils.isNotBlank(fulfillmentNo)){
                        if (StringUtils.isNotBlank(featuresMap.get("forwardFulfillmentOrderNo"))){
                            featuresMap.put("forwardFulfillmentOrderNo",featuresMap.get("forwardFulfillmentOrderNo") + "," + fulfillmentNo);
                        }else {
                            featuresMap.put("forwardFulfillmentOrderNo",fulfillmentNo);
                        }
                        allocateOrder.setFeatures(FeatureUtil.toString(featuresMap));
                        allocateOrderService.updateAllocateOrder(allocateOrder);
//                        com.epoch.app.crunifiedinventory.domain.allocateorder.dto.UpdateFeaturesRequest updateFeaturesRequest = new com.epoch.app.crunifiedinventory.domain.allocateorder.dto.UpdateFeaturesRequest();
//                        updateFeaturesRequest.setMainOrderCode(currentAllocateOrder.getCode());
//                        updateFeaturesRequest.setBizFeatures(FeatureUtil.toString(bizFeaturesMap));
//                        allocateOrderService.updateFeatures(updateFeaturesRequest);
                    }
                }
            }
        }
    }

    private void createForwardOrder(AllocateOrder allocateOrder,
                                    List<AllocateOrderDetail> allocateOrderDetailList,
                                    Map<String,String> map){
        CreateFulfillmentOrderReq req = new CreateFulfillmentOrderReq();
        if (StringUtils.isNotBlank(allocateOrder.getFromSys())){
            req.setFromSys(allocateOrder.getFromSys());
        }else {
            req.setFromSys("APP_SAP");
        }
        req.setBusinessType(StringUtils.isNotBlank(allocateOrder.getBusinessType()) ? allocateOrder.getBusinessType() : "11");
        //TODO 业务单据编码
        req.setBusinessUnitCode("6000");
        req.setRequestNo(UUID.randomUUID().toString().replaceAll("-",""));
        //调拨单号
        req.setSourceOrderNo(allocateOrder.getCode());
        //退单:调拨退单出库,  否:调拨出库
        if (Boolean.TRUE.equals(allocateOrder.getReturnOrder())){
            req.setRefOrderType(OrderTypeEnum.ALLOCATE_RETURN_OUTBOUND.getValue());
        }else {
            req.setRefOrderType(OrderTypeEnum.ALLOCATE_OUTBOUND.getValue());
        }
        //调出仓和调入仓属于同一个物理仓（虚拟移库） 更正逻辑改为如果调拨单创建时履约类型为虚拟移库,则这里传递为虚拟移库
//        if (Objects.equals(allocateOrder.getShipWarehouseId(),allocateOrder.getReceiveWarehouseId())){
        if (com.epoch.app.crunifiedinventory.model.enums.FulfillmentTypeEnum.VIRTUAL_TRANSFER.getValue().toString().equals(allocateOrder.getFulfillmentTypeCode())){
            req.setFulfillmentType(FulfillmentTypeEnum.EXTERNALWAREHOUSE_FULFILLMENT.getValue());
        }else {
            req.setFulfillmentType(FulfillmentTypeEnum.BIGWAREHOUSE_FULFILLMENT.getValue());
        }
        req.setAutoSubmit(Boolean.TRUE);
        //枚举：：1=普通，100=优先
        req.setPriority(allocateOrder.getPriority() == null ? "1" : allocateOrder.getPriority().toString());
        req.setProductGroupCode(allocateOrder.getProductGroup());
        Map<String, CargoZoneSDO> cargoZoneSDOMap = this.getCargoZoneSDOMap(Arrays.asList(allocateOrder.getShipAreaId(), allocateOrder.getReceiveAreaId(), allocateOrder.getShipWarehouseId(), allocateOrder.getReceiveWarehouseId()).stream().filter(StringUtils::isNotBlank)
                .collect(Collectors.toList()));
        Map<String, CargoZoneSDO> codeZoneSDOMap = this.getCargoZoneSDOMapByCodes(Arrays.asList(allocateOrder.getTransferWarehouseId()).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()));
        String logicShippingWarehouseCode = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getShipAreaId())).map(CargoZoneSDO::getCode).orElse(null);
        String logicShippingWarehouseName = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getShipAreaId())).map(CargoZoneSDO::getName).orElse(null);
        String shippingWarehouseCode = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getShipWarehouseId())).map(CargoZoneSDO::getCode).orElse(null);
        String shippingWarehouseName = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getShipWarehouseId())).map(CargoZoneSDO::getName).orElse(null);
        String logicReceivingWarehouseCode = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId())).map(CargoZoneSDO::getCode).orElse(null);
        String logicReceivingWarehouseName = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId())).map(CargoZoneSDO::getName).orElse(null);
        String receivingWarehouseCode = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getReceiveWarehouseId())).map(CargoZoneSDO::getCode).orElse(null);
        String receivingWarehouseName = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getReceiveWarehouseId())).map(CargoZoneSDO::getName).orElse(null);
        String transferWarehouseName = Optional.ofNullable(codeZoneSDOMap.get(allocateOrder.getTransferWarehouseId())).map(CargoZoneSDO::getName).orElse(null);
        Map<String,String> features = Maps.newHashMap();
        features.put(FeaturesKey.OUT_ALLOCATE_ORDER_ID,allocateOrder.getOutAllocateOrderId());
        //创建货场提货单时的入库单号
        Map<String, String> allocateOrderBizFeatures = FeatureUtil.fromString(allocateOrder.getBizFeatures());
        features.put(FeaturesKey.ORIGIN_PLAN_WMS_ORDER_ID,allocateOrderBizFeatures.get(FeaturesKey.ORIGIN_PLAN_WMS_ORDER_ID));
        if (Boolean.TRUE.equals(allocateOrder.getReturnOrder())){
            req.setLogicReceivingWarehouseCode(logicShippingWarehouseCode);
            req.setLogicReceivingWarehouse(logicShippingWarehouseName);
            req.setReceivingWarehouseCode(shippingWarehouseCode);
            req.setReceivingWarehouse(shippingWarehouseName);
            features.put(FeaturesKey.TRANSFER_ORDER_TARGET_LOGIC_WAREHOUSE_CODE,shippingWarehouseCode);
            if (ToolUtil.isTrainOrSea(allocateOrder.getShipMethod())){
                req.setLogicShippingWarehouseCode(allocateOrder.getTransferWarehouseId());
                req.setLogicShippingWarehouse(transferWarehouseName);
            }else {
                req.setLogicShippingWarehouseCode(logicReceivingWarehouseCode);
                req.setLogicShippingWarehouse(logicReceivingWarehouseName);
                req.setShippingWarehouseCode(receivingWarehouseCode);
                req.setShippingWarehouse(receivingWarehouseName);
            }
            CargoZoneSDO cargoZoneSDO = cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId());
            if (cargoZoneSDO != null && cargoZoneSDO.getFeature() != null){
                req.setSoldToPartyCode(cargoZoneSDO.getFeature().get("sapInternalSalesBPCode"));
                req.setShipToPartyCode(cargoZoneSDO.getFeature().get("sapInternalDeliveryBPCode"));
            }
        }else {
            req.setLogicShippingWarehouseCode(logicShippingWarehouseCode);
            req.setLogicShippingWarehouse(logicShippingWarehouseName);
            req.setShippingWarehouseCode(shippingWarehouseCode);
            req.setShippingWarehouse(shippingWarehouseName);
            features.put(FeaturesKey.TRANSFER_ORDER_TARGET_LOGIC_WAREHOUSE_CODE,logicReceivingWarehouseCode);
            if (ToolUtil.isTrainOrSea(allocateOrder.getShipMethod())){
                req.setLogicReceivingWarehouseCode(allocateOrder.getTransferWarehouseId());
                req.setLogicReceivingWarehouse(transferWarehouseName);
                CargoZoneSDO cargoZoneSDO = cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId());
                if (cargoZoneSDO != null && MapUtils.isNotEmpty(cargoZoneSDO.getFeature())){
                    req.setSoldToPartyCode(cargoZoneSDO.getFeature().get("sapInternalSalesBPCode"));
                    req.setShipToPartyCode(cargoZoneSDO.getFeature().get("sapInternalDeliveryBPCode"));
                }
            }else {
                req.setLogicReceivingWarehouseCode(logicReceivingWarehouseCode);
                req.setLogicReceivingWarehouse(logicReceivingWarehouseName);
                req.setReceivingWarehouseCode(receivingWarehouseCode);
                req.setReceivingWarehouse(receivingWarehouseName);
                //客户售达方编码 来自于仓库上的售达方编码
                CargoZoneSDO cargoZoneSDO = cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId());
                if (cargoZoneSDO != null && MapUtils.isNotEmpty(cargoZoneSDO.getFeature())){
                    req.setSoldToPartyCode(cargoZoneSDO.getFeature().get("sapInternalSalesBPCode"));
                    req.setShipToPartyCode(cargoZoneSDO.getFeature().get("sapInternalDeliveryBPCode"));
                }
            }
        }
        Map<String, String> mainBizFeaturesMap = FeatureUtil.fromString(allocateOrder.getBizFeatures());
        if (StringUtils.isNotBlank(mainBizFeaturesMap.get(FeaturesKey.TRANSFER_OUT_BIZ_UNIT))){
            features.put(FeaturesKey.TRANSFER_OUT_BIZ_UNIT,mainBizFeaturesMap.get(FeaturesKey.TRANSFER_OUT_BIZ_UNIT));
        }
        if (StringUtils.isNotBlank(mainBizFeaturesMap.get(FeaturesKey.BIZ_UNIT))){
            features.put(FeaturesKey.BIZ_UNIT,mainBizFeaturesMap.get(FeaturesKey.BIZ_UNIT));
        }
        if (MapUtils.isNotEmpty(features)){
            req.setFeatures(FeatureUtil.toString(features));
            req.setBizFeatures(JSONObject.toJSONString(features));
        }
        req.setProductGroupCode(StringUtils.isNotBlank(allocateOrder.getProductGroup()) ? allocateOrder.getProductGroup() : "11");
        req.setChannelCode("90");
        //6000?
        req.setSalesOrganizationCode("6000");
        //TODO 送达方 售达方 选择仓库上的, 待定
//            req.setShipToPartyCode();
//        req.setCreator(allocateOrder.getCreator());
        req.setExpectedDeliveryTime(Objects.isNull(allocateOrder.getExpectedDeliveryDate()) ? null :
                DateFormatUtil.toString(allocateOrder.getExpectedDeliveryDate(),DateFormatUtil.TIME_PATTERN));
        req.setShippingMethodCode(allocateOrder.getShipMethod() == null ? null : allocateOrder.getShipMethod().toString());
        req.setRemark(allocateOrder.getRemark());

        List<CreateFulfillmentOrderDetailDTO> detailDTOList = Lists.newArrayList();
        allocateOrderDetailList.forEach(detail -> {
            CreateFulfillmentOrderDetailDTO detailDTO = new CreateFulfillmentOrderDetailDTO();
            detailDTO.setSourceOrderLineNo(detail.getLineNo() == null ? null : detail.getLineNo().toString());
            detailDTO.setRefOrderNo(allocateOrder.getCode());
            detailDTO.setRefOrderLineNo(detail.getLineNo() == null ? null : detail.getLineNo().toString());
            detailDTO.setMaterialCode(detail.getScItemCode());
            detailDTO.setRefOrderLineNo(detail.getLineNo() == null ? null : detail.getLineNo().toString());
            detailDTO.setRefOrderCreateTime(allocateOrder.getGmt_create() == null ? null :
                    DateFormatUtil.toString(allocateOrder.getGmt_create(),"yyyy-MM-dd HH:mm:ss"));
            detailDTO.setProductionDate(detail.getExpectedProduceDate() == null ? null :
                    DateFormatUtil.toString(detail.getExpectedProduceDate(),"yyyy-MM-dd"));
            detailDTO.setSalesUnitCode(StringUtils.isBlank(detail.getUnit()) ? "PC" : detail.getUnit());
            if (Boolean.TRUE.equals(allocateOrder.getReturnOrder())) {
                detailDTO.setSaleQuantity(new BigDecimal(detail.getQuantity().trim()));
                detailDTO.setQuantity(new BigDecimal(detail.getQuantity().trim()));
            } else {
                detailDTO.setSaleQuantity(new BigDecimal(detail.getConfirmQuantity().trim()));
                detailDTO.setQuantity(new BigDecimal(detail.getConfirmQuantity().trim()));
            }
            detailDTO.setShippingUnitCode(StringUtils.isBlank(detail.getUnit()) ? "PC" : detail.getUnit());
            detailDTO.setRemark(detail.getRemarks());
            detailDTO.setClose(Boolean.TRUE.equals(detail.getClose()) ? 1 : 0);
            detailDTO.setCloseReasonCode(detail.getCloseCode());
            detailDTO.setCloseReason(detail.getCloseReason());
            Map<String,String> featuresMap = Maps.newHashMap();
            if (StringUtils.isNotBlank(detail.getOutAllocateOrderLineId())){
                featuresMap.put(FeaturesKey.OUT_ALLOCATE_ORDER_LINE_ID,detail.getOutAllocateOrderLineId());
            }
            if (StringUtils.isNotBlank(detail.getBizFeatures())){
                Map<String, String> detailBizFeatures = FeatureUtil.fromString(detail.getBizFeatures());
                featuresMap.put(FeaturesKey.BIZ_UNIT_RATIO,detailBizFeatures.get(FeaturesKey.BIZ_UNIT_RATIO));
                if (StringUtils.isNotBlank(detailBizFeatures.get(FeaturesKey.BIZ_UNIT_RATIO))){
                    JSONObject bizFeaturesJsonObject = new JSONObject();
                    bizFeaturesJsonObject.put(FeaturesKey.BIZ_UNIT_RATIO,detailBizFeatures.get(FeaturesKey.BIZ_UNIT_RATIO));
                    detailDTO.setBizFeatures(bizFeaturesJsonObject.toJSONString());
                }

            }
            detailDTO.setFeatures(FeatureUtil.toString(featuresMap));
            if (AllocateOrderTypeEnum.FREIGHT_YARD_PICKUP.getType().equals(allocateOrder.getType()) &&
                    Boolean.FALSE.equals(allocateOrder.getReturnOrder())) {
                detailDTO.setBatchNo(FeatureUtil.fromString(detail.getBizFeatures()).get("batchNo"));
            }
            detailDTOList.add(detailDTO);
        });
        req.setDetailList(detailDTOList);
        log.info("syncAllocateOrder_create_order_request:{}",JSON.toJSONString(req));
        com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result<FulfillmentOrderResponse> order;
        if (FulfillmentTypeEnum.EXTERNALWAREHOUSE_FULFILLMENT.getValue().equals(req.getFulfillmentType())){
            order = fulfillmentOrderAbilityService.createSalesOrderForExternalWarehouse(req);
        }else {
            order = fulfillmentOrderOpenApi.createOrder(req);
        }
        log.info("syncAllocateOrder_create_order_response:{}",JSON.toJSONString(order));
        if (order != null && order.isSuccess()){
            map.put("forwardFulfillmentOrderNo",order.getResult().getFulfillmentOrderNo());
            allocateOrder.setFeatures(FeatureUtil.toString(map));
            allocateOrderService.updateAllocateOrder(allocateOrder);
            log.info("update_createFulfillmentOrder_result:{}",JSON.toJSONString(order));
            UpdateFulfillmentOrderFeaturesReq featuresReq = buildUpdateFulfillmentOrderFeaturesReq(req, order.getResult());
            log.info("updateFulfillmentOrderFeatures_request:{}",JSON.toJSONString(featuresReq));
            com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result updateFeatures = fulfillmentOrderAbilityService.updateFulfillmentOrderFeatures(featuresReq);
            log.info("updateFulfillmentOrderFeatures_result:{}",JSON.toJSONString(updateFeatures));
        }
    }

    /**
     * 008同步时关闭预报单和调拨单
     * @param origin
     * @param current
     */
    private void closeFulfillmentOrderAndAllocateOrder(com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntity origin,
                                                       com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntity current){
        List<AllocateOrderDetail> closeList = Nullable.stream(current.getDetailList()).filter(currentDetail -> Boolean.TRUE.equals(currentDetail.getClose())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(closeList)){
            log.info("AllocateOrderWriteServiceImpl_close_is_empty");
            return;
        }
        //从调拨单中找出此次关闭的行
        List<AllocateOrderDetail> closeDetailList = Nullable.stream(current.getDetailList())
                .filter(currentDetail -> Boolean.TRUE.equals(currentDetail.getClose()))
                .filter(currentDetail -> origin.getDetailList().stream()
                        .filter(originDetail -> Objects.equals(currentDetail.getLineNo(), originDetail.getLineNo()))
                        .anyMatch(originDetail -> !Boolean.TRUE.equals(originDetail.getClose())))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(closeDetailList)){
            log.info("AllocateOrderWriteServiceImpl_close_not_need_close");
            //找出履约单对应的出库单
            List<WarehousingOrderDTO> wmsOrderList = Lists.newArrayList();
            WmsOrderQueryRequest wmsOrderQueryRequest = new WmsOrderQueryRequest();
            wmsOrderQueryRequest.setBizOrderId(current.getAllocateOrder().getCode());
            wmsOrderQueryRequest.setContainSubOrders(true);
            com.alibaba.cz.base.tool.result.Result<WarehousingOrdersQueryResponse> wmsQueryResult = warehousingOrderReadService.queryWmsOrderByOtherOrder(wmsOrderQueryRequest);
            log.info("AllocateOrderWriteServiceImpl_close_queryWmsResult:{}",JSON.toJSONString(wmsQueryResult));
            //将出库明细1放到列表中
            if (wmsQueryResult != null && wmsQueryResult.getResult() != null && CollectionUtils.isNotEmpty(wmsQueryResult.getResult().getWarehousingOrders())){
                wmsOrderList.addAll(wmsQueryResult.getResult().getWarehousingOrders());
            }
            closeAllocateOrder(current,closeList,wmsOrderList);
            return;
        }
        log.info("AllocateOrderWriteServiceImpl_close_filter_list:{}",JSON.toJSONString(closeDetailList));
        //查出调拨单所有对应的履约单
        AllocateOrder currentAllocateOrder = current.getAllocateOrder();
        SearchFulfullmentOrderReq searchFulfullmentOrderReq = new SearchFulfullmentOrderReq();
        searchFulfullmentOrderReq.setSourceOrderNo(currentAllocateOrder.getCode());
        searchFulfullmentOrderReq.setFulfillmentDirectionType(FulfillmentDirectionTypeEnum.FORWARD.getValue());
        com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result<List<FulfillmentGetRes>> searchFulfillmentOrder = fulfillmentOrderAbilityService.searchFulfullmentOrder(searchFulfullmentOrderReq);
        log.info("AllocateOrderWriteServiceImpl_close_searchFulfillmentOrder_result:{}",JSON.toJSONString(searchFulfillmentOrder));
        List<WarehousingOrderDTO> wmsOrderList = Lists.newArrayList();
        if (searchFulfillmentOrder != null && CollectionUtils.isNotEmpty(searchFulfillmentOrder.getResult())){
            //调拨单关联的所有正向履约单
            List<FulfillmentGetRes> fulfillmentGetResList = searchFulfillmentOrder.getResult();
            //过滤出满足的正向履约单  待发货 /部分发货
            List<FulfillmentGetRes> filterFulfillmentList = fulfillmentGetResList.stream()
                    .map(f -> {
                        List<FulfillmentDetailGetRes> matchDetails = Nullable.stream(f.getDetailList()).filter(d ->
                                CompareUtil.anyOf(d.getStatus(), FulfillmentOrderStatusEnum.WAIT_SEND.getValue().toString(), FulfillmentOrderStatusEnum.PART_SEND.getValue().toString())
                        ).collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(matchDetails)){
                            f.setDetailList(matchDetails);
                            return f;
                        }
                        return null;
                    }).filter(Objects::nonNull).collect(Collectors.toList());
            log.info("AllocateOrderWriteServiceImpl_close_filter_order_list:{}",JSON.toJSONString(filterFulfillmentList));
            if (CollectionUtils.isNotEmpty(filterFulfillmentList)){
                //找出履约单对应的出库单
                WmsOrderQueryRequest wmsOrderQueryRequest = new WmsOrderQueryRequest();
                wmsOrderQueryRequest.setBizOrderId(currentAllocateOrder.getCode());
                wmsOrderQueryRequest.setContainSubOrders(true);
                com.alibaba.cz.base.tool.result.Result<WarehousingOrdersQueryResponse> wmsQueryResult = warehousingOrderReadService.queryWmsOrderByOtherOrder(wmsOrderQueryRequest);
                log.info("AllocateOrderWriteServiceImpl_close_queryWmsResult:{}",JSON.toJSONString(wmsQueryResult));
                //将出库明细1放到列表中
                if (wmsQueryResult != null && wmsQueryResult.getResult() != null && CollectionUtils.isNotEmpty(wmsQueryResult.getResult().getWarehousingOrders())){
                    wmsOrderList.addAll(wmsQueryResult.getResult().getWarehousingOrders());
                }
//                Optional.ofNullable(wmsQueryResult).map(com.alibaba.cz.base.tool.result.Result::getResult)
//                        .map(WarehousingOrdersQueryResponse::getWarehousingOrders)
//                        .filter(CollectionUtils::isNotEmpty).ifPresent(w -> wmsOrderList.addAll(w));
                //过滤出符合的出入库单明细1
                List<WarehousingOrderDTO> warehousingOrderDTOList = Optional.ofNullable(wmsQueryResult)
                        .map(com.alibaba.cz.base.tool.result.Result::getResult)
                        .map(WarehousingOrdersQueryResponse::getWarehousingOrders)
                        .orElse(Lists.newArrayList())
                        .stream().filter(warehousingOrderDTO -> filterFulfillmentList.stream().map(FulfillmentGetRes::getFulfillmentOrderNo)
                                .anyMatch(fulfillmentNo -> fulfillmentNo.equals(warehousingOrderDTO.getFulfillmentOrderId())))
                        .collect(Collectors.toList());
                log.info("AllocateOrderWriteServiceImpl_close_filter_wms:{}",JSON.toJSONString(warehousingOrderDTOList));
                FinishReq finishReq = buildCloseFulfillmentOrderReq(currentAllocateOrder,
                        closeDetailList,
                        fulfillmentGetResList,
                        warehousingOrderDTOList);
                log.info("AllocateOrderWriteServiceImpl_close_finish_request:{}",JSON.toJSONString(finishReq));
                if (finishReq != null && CollectionUtils.isNotEmpty(finishReq.getFulfillmentOrderInfoList())){
                    com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result<List<BatchCloseFulfillmentOrderResponse>> finish =
                            fulfillmentOrderAbilityService.finish(finishReq);
                    log.info("AllocateOrderWriteServiceImpl_close_finish_result:{}",JSON.toJSONString(finish));
                    if (Objects.isNull(finish) || !finish.isSuccess()){
                        throw new FacadeException("OTS-03-005-00-15-242");
                    }
                }

            }

        }
        //关闭逻辑

        closeAllocateOrder(current,closeList,wmsOrderList);
    }

    private void closeAllocateOrder(AllocateOrderEntity current, List<AllocateOrderDetail> closeDetailList, List<WarehousingOrderDTO> warehousingOrderDTOList){
        log.info("AllocateOrderWriteServiceImpl_close_closeAllocateOrder_request:{},wms:{}",JSON.toJSONString(closeDetailList),JSON.toJSONString(warehousingOrderDTOList));
        Result<Boolean> close = allocateOrderCloseService.closeAllocateOrder(current, closeDetailList, warehousingOrderDTOList);
        log.info("AllocateOrderWriteServiceImpl_close_closeAllocateOrder_result:{}",JSON.toJSONString(close));
    }


    private void closeAllocateOrder(List<AllocateOrderDetail> closeDetailList,AllocateOrder currentAllocateOrder){
        //没有履约单, 关闭调拨单
//        AllocateOrderCloseRequest allocateOrderCloseRequest = new AllocateOrderCloseRequest();
//        allocateOrderCloseRequest.setOperatorId("sap");
//        List<AllocateOrderCloseDTO> allocateOrderCloseDTOList = Lists.newArrayList();
//        allocateOrderCloseRequest.setCloseList(allocateOrderCloseDTOList);
//        closeDetailList.forEach(closeDetail -> {
//            AllocateOrderCloseDTO allocateOrderCloseDTO = new AllocateOrderCloseDTO();
//            allocateOrderCloseDTO.setCloseCode(StringUtils.isBlank(closeDetail.getCloseCode()) ? "14" : closeDetail.getCloseCode());
//            allocateOrderCloseDTO.setOutAllocateOrderLineNo(closeDetail.getOutAllocateOrderLineId());
//            allocateOrderCloseDTO.setTransferOrderCode(currentAllocateOrder.getCode());
//            allocateOrderCloseDTO.setDetailNo(closeDetail.getLineNo() == null ? null :closeDetail.getLineNo().toString());
//            allocateOrderCloseDTOList.add(allocateOrderCloseDTO);
//        });
//        log.info("AllocateOrderWriteServiceImpl_close_closeAllocateOrder_request:{}",JSON.toJSONString(allocateOrderCloseRequest));


//        TransferOrderCloseRequest transferOrderCloseRequest = new TransferOrderCloseRequest();
//        transferOrderCloseRequest.setOperatorId("sap");
//        transferOrderCloseRequest.setBusinessType(currentAllocateOrder.getBusinessType());
//        transferOrderCloseRequest.setFromSys(currentAllocateOrder.getFromSys());
//        List<TransferOrderCloseDetail> closeList = Lists.newArrayList();
//        closeDetailList.forEach(closeDetail -> {
//            TransferOrderCloseDetail transferOrderCloseDetail = new TransferOrderCloseDetail();
//            transferOrderCloseDetail.setCloseCode(StringUtils.isBlank(closeDetail.getCloseCode()) ? "14" : closeDetail.getCloseCode());
////            transferOrderCloseDetail.setDetailNo(closeDetail.getLineNo() == null ? null : closeDetail.getLineNo());
//            transferOrderCloseDetail.setTransferOrderCode(currentAllocateOrder.getCode());
//            transferOrderCloseDetail.setDetailNo(closeDetail.getLineNo() == null ? null :closeDetail.getLineNo().toString());
//            closeList.add(transferOrderCloseDetail);
//        });
//        transferOrderCloseRequest.setCloseList(closeList);
//        log.info("AllocateOrderWriteServiceImpl_close_closeAllocateOrder_request:{}",JSON.toJSONString(transferOrderCloseRequest));
//        Result<TransferOrderCloseResponse> transferOrderCloseResponseResult = allocateOrderCloseService.closeAllocateOrder(transferOrderCloseRequest);
////        AllocateOrderCloseResponse allocateOrderCloseResponse = closeAllocateOrder(allocateOrderCloseRequest);
//        log.info("AllocateOrderWriteServiceImpl_close_closeAllocateOrder_result:{}",JSON.toJSONString(transferOrderCloseResponseResult));

    }


    private FinishReq buildCloseFulfillmentOrderReq(AllocateOrder currentAllocateOrder,
                                                    List<AllocateOrderDetail> closeDetailList,
                                                    List<FulfillmentGetRes> fulfillmentGetResList,
                                                    List<WarehousingOrderDTO> warehousingOrderDTOList){
        FinishReq finishReq = new FinishReq();
        finishReq.setBusinessType(currentAllocateOrder.getBusinessType());
        finishReq.setFromSys(currentAllocateOrder.getFromSys());
        //TODO 是否是一直6000
        finishReq.setBusinessUnitCode("6000");
        finishReq.setUpdater("system");
        List<FinishReq.FulfillmentOrderInfo> fulfillmentOrderInfos = Lists.newArrayList();
        //请求履约批量关闭
        finishReq.setFulfillmentOrderInfoList(fulfillmentOrderInfos);
        closeDetailList.forEach(closeDetail -> {
            log.info("forEach_closeDetail:{}",JSON.toJSONString(closeDetail));
            //循环每个履约单,
            fulfillmentGetResList.forEach(fulfillmentGetRes -> {
                buildCloseFulfillmentOrderDetailReqList(fulfillmentGetRes,
                        closeDetail,
                        warehousingOrderDTOList,
                        fulfillmentOrderInfos);
//                FinishReq.FulfillmentOrderInfo fulfillmentOrderInfo = new FinishReq.FulfillmentOrderInfo();
//                fulfillmentOrderInfo.setFulfillmentOrderNo(fulfillmentGetRes.getFulfillmentOrderNo());
//                Nullable.stream(fulfillmentGetRes.getDetailList())
//                        //过滤出符合关闭的行
//                        .filter(fulfillmentDetailGetRes -> Objects.equals(closeDetail.getLineNo(),fulfillmentDetailGetRes.getRefOrderLineNo()))
//                        //过滤出待发货和部分发货.  忽略: 已完成/已取消; 忽略: 待提交/待推送
//                        .filter(fulfillmentDetailGetRes -> CompareUtil.anyOf(fulfillmentDetailGetRes.getStatus(), FulfillmentOrderStatusEnum.WAIT_SEND.getValue().toString(),FulfillmentOrderStatusEnum.PART_SEND.getValue().toString()))
//                        .forEach(fulfillmentDetailGetRes -> {
//                            List<WarehousingOrderDTO> matchWmsOrderList = warehousingOrderDTOList.stream()
//                                    //针对这个履约单,匹配出对应的wms主单
//                                    .filter(warehousingOrderDTO -> fulfillmentGetRes.getFulfillmentOrderNo().equals(warehousingOrderDTO.getFulfillmentOrderId()))
//                                    .collect(Collectors.toList());
//                            if (CollectionUtils.isEmpty(matchWmsOrderList)){
//                                fulfillmentOrderInfo.setFulfillmentSubOrderNo(fulfillmentDetailGetRes.getLineNumber());
//                                fulfillmentOrderInfos.add(fulfillmentOrderInfo);
//                            }else {
//                                BigDecimal sumWmsQuantity = matchWmsOrderList.stream().map(WarehousingOrderDTO::getWmsOrderDetailList).filter(CollectionUtils::isNotEmpty)
//                                        .flatMap(Collection::stream).map(WmsOrderDetailDTO::getGoodsQuantity)
//                                        .filter(Objects::nonNull).map(BigDecimal::new).map(q -> q.movePointLeft(3))
//                                        .reduce(BigDecimal.ZERO, BigDecimal::add);
//                                if (fulfillmentDetailGetRes.getQuantity().compareTo(sumWmsQuantity) > 0){
//                                    fulfillmentOrderInfo.setFulfillmentSubOrderNo(fulfillmentDetailGetRes.getLineNumber());
//                                    fulfillmentOrderInfos.add(fulfillmentOrderInfo);
//                                }
//                            }
//                        });

            });
        });
        return finishReq;
    }

    private void buildCloseFulfillmentOrderDetailReqList(FulfillmentGetRes fulfillmentGetRes,
                                                         AllocateOrderDetail closeDetail,
                                                         List<WarehousingOrderDTO> warehousingOrderDTOList,
                                                         List<FinishReq.FulfillmentOrderInfo> fulfillmentOrderInfos){
        log.info("buildCloseFulfillmentOrderDetailReqList,fulfillmentGetRes:{},closeDetail:{},warehousingOrderDTOList:{},fulfillmentOrderInfos:{}",
                JSON.toJSONString(fulfillmentGetRes),JSON.toJSONString(closeDetail),JSON.toJSONString(warehousingOrderDTOList),JSON.toJSONString(fulfillmentOrderInfos));
        FinishReq.FulfillmentOrderInfo fulfillmentOrderInfo = new FinishReq.FulfillmentOrderInfo();
        fulfillmentOrderInfo.setFulfillmentOrderNo(fulfillmentGetRes.getFulfillmentOrderNo());
        Nullable.stream(fulfillmentGetRes.getDetailList())
                //过滤出符合关闭的行
                .filter(fulfillmentDetailGetRes -> Objects.equals(closeDetail.getLineNo() == null ? null : closeDetail.getLineNo().toString(),fulfillmentDetailGetRes.getRefOrderLineNo()))
                //过滤出待发货和部分发货.  忽略: 已完成/已取消; 忽略: 待提交/待推送
                .filter(fulfillmentDetailGetRes -> CompareUtil.anyOf(fulfillmentDetailGetRes.getStatus(), FulfillmentOrderStatusEnum.WAIT_SEND.getValue().toString(),FulfillmentOrderStatusEnum.PART_SEND.getValue().toString()))
                .forEach(fulfillmentDetailGetRes -> {
                    List<WarehousingOrderDTO> matchWmsOrderList = warehousingOrderDTOList.stream()
                            //针对这个履约单,匹配出对应的wms主单
                            .filter(warehousingOrderDTO -> fulfillmentGetRes.getFulfillmentOrderNo().equals(warehousingOrderDTO.getFulfillmentOrderId()))
                            .collect(Collectors.toList());
                    if (CollectionUtils.isEmpty(matchWmsOrderList)){
                        //没有匹配上明细也关闭
                        log.info("AllocateOrderWriteServiceImpl_close_not_match_wms:{}",JSON.toJSONString(fulfillmentDetailGetRes));
                        fulfillmentOrderInfo.setFulfillmentSubOrderNo(fulfillmentDetailGetRes.getLineNumber());
                        fulfillmentOrderInfos.add(fulfillmentOrderInfo);
                    }else {
                        //所有wms明细1,
                        BigDecimal sumWmsQuantity = matchWmsOrderList.stream().map(WarehousingOrderDTO::getWmsOrderDetailList).filter(CollectionUtils::isNotEmpty)
                                .flatMap(Collection::stream)
                                .filter(w -> Objects.equals(w.getFulfillmentSubOrderId(),fulfillmentDetailGetRes.getLineNumber() == null ? null: fulfillmentDetailGetRes.getLineNumber().toString()))
                                .map(WmsOrderDetailDTO::getGoodsQuantity)
                                .filter(Objects::nonNull).map(BigDecimal::new)
                                //数量查出来时已经缩小了1000倍
//                                .map(q -> q.movePointLeft(3))
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        log.info("quantity:{},sumWmsQuantity:{}",JSON.toJSONString(fulfillmentDetailGetRes.getQuantity()),JSON.toJSONString(sumWmsQuantity));
                        if (fulfillmentDetailGetRes.getQuantity().compareTo(sumWmsQuantity) > 0){
                            log.info("AllocateOrderWriteServiceImpl_close_more_than:{}",JSON.toJSONString(fulfillmentDetailGetRes));
                            fulfillmentOrderInfo.setFulfillmentSubOrderNo(fulfillmentDetailGetRes.getLineNumber());
                            fulfillmentOrderInfos.add(fulfillmentOrderInfo);
                            return;
                        }
                        log.info("AllocateOrderWriteServiceImpl_close_less_than_or_equal:{}",JSON.toJSONString(fulfillmentDetailGetRes));
                    }
                });

    }

    /**
     * 构建履约单明细
     * 008操作前的调拨单明细
     * 退单没有确认数量
     */
    public List<CreateFulfillmentOrderDetailDTO> buildCreateFulfillmentOrderDetailDTOList(List<AllocateOrderDetail> originDetailList,
                                                                                          List<AllocateOrderDetail> currentDetailList,
                                                                                          AllocateOrder currentAllocateOrder,
                                                                                          AllocateOrderSyncRequest syncRequest,
                                                                                          List<FinishReq.FulfillmentOrderInfo> finishDetailList,
                                                                                          List<CreateFulfillmentOrderDetailDTO> createFulfillmentOrderDetailDTOList,
                                                                                          List<FulfillmentGetRes> fulfillmentGetResList,
                                                                                          List<AllocateOrderDetail> updateCloseDetailList){
        log.info("originDetailList:{},currentDetailList:{},syncRequest:{}",JSON.toJSONString(originDetailList),JSON.toJSONString(currentDetailList),JSON.toJSONString(syncRequest));
        List<AllocateOrderScItemDetailDTO> existConfirmQuantityDetailList = Lists.newArrayList();
        if (Boolean.TRUE.equals(syncRequest.getReturnOrder())) {
            existConfirmQuantityDetailList = syncRequest.getAllocateOrderScItemDetails().stream().filter(
                    detailDTO -> StringUtils.isNotBlank(detailDTO.getQuantity())).collect(Collectors.toList());
        } else {
            existConfirmQuantityDetailList = syncRequest.getAllocateOrderScItemDetails().stream().filter(
                    detailDTO -> StringUtils.isNotBlank(detailDTO.getConfirmQuantity()))
                    .collect(Collectors.toList());//这里去掉了过滤确认数量>0的,因为第一次有确认数量,第二次确认数量是0的需要操作这个差量, 即使现在是0
        }
        if (CollectionUtils.isEmpty(existConfirmQuantityDetailList)){
            //如果008没有一行是有确认数量的则跳过
            log.info("buildCreateFulfillmentOrderDetailDTOList_not_exist_confirmQuantity");
            return null;
        }
        List<FulfillmentGetRes> fulfillmentGetRes = new ArrayList<>();
        // 退单时由于需要通过调拨单数量创建履约单,因此需要判断当前调拨单有没有创建过履约单,如果没有创建过履约单无需比较调拨单修改前后的数量差值,直接进行履约单创建
        if (Boolean.TRUE.equals(syncRequest.getReturnOrder())) {
            fulfillmentGetRes = searchFulfillmentOrder(syncRequest.getCode(), FulfillmentDirectionTypeEnum.FORWARD.getValue());
        }
        List<CreateFulfillmentOrderDetailDTO> detailReqList = Lists.newArrayList();
        //过滤出非关闭的明细, 关闭的明细走
        currentDetailList = currentDetailList.stream().filter(allocateOrderDetail -> !Boolean.TRUE.equals(allocateOrderDetail.getClose())).collect(Collectors.toList());
        //只需要正向履约单的wms出库明细
        List<WarehousingOrderDTO> warehousingOrderDTOList = filterForwardWmsOrderList(currentAllocateOrder.getCode(),fulfillmentGetResList);
        //这里需要过滤出正向的出库明细
        for (AllocateOrderDetail currentDetail : currentDetailList) {
            AllocateOrderScItemDetailDTO syncDetail = existConfirmQuantityDetailList.stream().filter(detailDTO ->
                            Objects.equals(InfoUtil.deleteZeroPrefix(detailDTO.getOutAllocateOrderLineId()), currentDetail.getOutAllocateOrderLineId()))
                    .findFirst().orElse(null);
            if (syncDetail == null){
                //这里是匹配外部行号的, 有确认数量的才需要创建履约单
                log.info("buildCreateFulfillmentOrderDetailDTOList_outAllocateOrderLineId_not_match:{}",JSON.toJSONString(currentDetail));
                continue;
            }
            AllocateOrderDetail originDetail = originDetailList.stream().filter(allocateOrderDetail -> Objects.equals(allocateOrderDetail.getLineNo(), currentDetail.getLineNo()))
                    .findFirst().orElse(null);
            if (originDetail == null){
                //TODO 这里作为新增行, 可能需要创建履约单,先跳过.
                log.info("buildCreateFulfillmentOrderDetailDTOList_new_line:{}",JSON.toJSONString(currentDetail));
                BigDecimal quantity  = BigDecimal.ZERO;
                if (Boolean.TRUE.equals(syncRequest.getReturnOrder())) {
                    quantity = Optional.ofNullable(currentDetail.getQuantity()).map(String::trim).map(BigDecimal::new).orElse(BigDecimal.ZERO);
                }else {
                    quantity = Optional.ofNullable(currentDetail.getConfirmQuantity()).map(String::trim).map(BigDecimal::new).orElse(BigDecimal.ZERO);
                }
                if (quantity.compareTo(BigDecimal.ZERO) > 0){
                    detailReqList.add(composeDetailReq(currentAllocateOrder,currentDetail,quantity));
                    log.info("buildCreateFulfillmentOrderDetailDTOList_new_line:{}",JSON.toJSONString(detailReqList));
                }
                continue;
            }
            //获取数量
            BigDecimal originConfirmQuantity = BigDecimal.ZERO;
            BigDecimal currentConfirmQuantity = BigDecimal.ZERO;
            if (Boolean.TRUE.equals(syncRequest.getReturnOrder())) {
                originConfirmQuantity = Optional.ofNullable(originDetail.getQuantity()).map(String::trim).map(BigDecimal::new).orElse(BigDecimal.ZERO);
                currentConfirmQuantity = Optional.ofNullable(currentDetail.getQuantity()).map(String::trim).map(BigDecimal::new).orElse(BigDecimal.ZERO);
            } else {
                originConfirmQuantity = Optional.ofNullable(originDetail.getConfirmQuantity()).map(String::trim).map(BigDecimal::new).orElse(BigDecimal.ZERO);
                currentConfirmQuantity = Optional.ofNullable(currentDetail.getConfirmQuantity()).map(String::trim).map(BigDecimal::new).orElse(BigDecimal.ZERO);
            }
            BigDecimal quantity = currentConfirmQuantity.subtract(originConfirmQuantity);
            log.info("originConfirmQuantity:{},currentConfirmQuantity:{},quantity:{}",JSON.toJSONString(originConfirmQuantity),
                    JSON.toJSONString(currentConfirmQuantity),JSON.toJSONString(quantity));
            if (Boolean.TRUE.equals(syncRequest.getReturnOrder()) && CollectionUtils.isEmpty(fulfillmentGetRes)) {
                quantity = currentConfirmQuantity;
            }
            //如果当前的数量 < 之前的数量
            List<AllocateOrderDetail> needCloseFulfillmentList = Lists.newArrayList();
            // 赋值 注意数量正负 看看挪上去
            if (quantity.compareTo(BigDecimal.ZERO) < 0 ){
                //阻断
                BigDecimal sumQuantity = Nullable.stream(warehousingOrderDTOList).map(WarehousingOrderDTO::getWmsOrderDetailList)
                        .filter(CollectionUtils::isNotEmpty).flatMap(Collection::stream)
                        .filter(Objects::nonNull).filter(wmsOrderDetailDTO -> Objects.equals(wmsOrderDetailDTO.getBizSubOrderId(), currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString()))
                        .map(WmsOrderDetailDTO::getGoodsQuantity)
                        .filter(Objects::nonNull)
                        .map(BigDecimal::new)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                log.info("sapSync_sumQuantity:{},",JSON.toJSONString(sumQuantity));
                if (currentConfirmQuantity.compareTo(sumQuantity) < 0){
                    log.info("less_than,currentConfirmQuantity:{},sumQuantity:{}",JSON.toJSONString(currentConfirmQuantity),JSON.toJSONString(sumQuantity));
                    continue;
                }else {
                    //查出所有的履约单, 这里只查正向
//                    List<FulfillmentGetRes> fulfillmentGetResList = searchFulfillmentOrder(currentAllocateOrder.getCode(), FulfillmentDirectionTypeEnum.FORWARD.getValue());
                    if (CollectionUtils.isEmpty(fulfillmentGetResList)){
                        log.info("fulfillmentGetResList_is_empty:{}",JSON.toJSONString(currentDetail));
                        continue;
                    }
                    BigDecimal fulfillmentOrderQuantity = fulfillmentGetResList.stream().filter(Objects::nonNull).map(FulfillmentGetRes::getDetailList)
                            .filter(CollectionUtils::isNotEmpty).flatMap(Collection::stream)
                            .filter(Objects::nonNull)
                            .filter(f -> Objects.equals(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString(), f.getRefOrderLineNo()))
                            .map(FulfillmentDetailGetRes::getQuantity)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    log.info("fulfillmentOrderQuantity_compareTo,fulfillmentOrderQuantity:{},sumQuantity:{}",JSON.toJSONString(fulfillmentOrderQuantity),JSON.toJSONString(sumQuantity));
                    if (fulfillmentOrderQuantity.compareTo(sumQuantity) > 0){
                        fulfillmentGetResList.stream().map(f -> {
                            List<FulfillmentDetailGetRes> detailGetResList = f.getDetailList().stream().filter(d -> Objects.equals(d.getRefOrderLineNo(), currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString()))
                                    .collect(Collectors.toList());
                            if (CollectionUtils.isNotEmpty(detailGetResList)){
                                f.setDetailList(detailGetResList);
                                return f;
                            }
                            return null;
                        }).filter(Objects::nonNull).forEach(f -> {
                            Nullable.stream(f.getDetailList()).forEach(d -> {
                                FinishReq.FulfillmentOrderInfo info = new FinishReq.FulfillmentOrderInfo();
                                info.setFulfillmentOrderNo(f.getFulfillmentOrderNo());
                                info.setFulfillmentSubOrderNo(d.getLineNumber());
                                finishDetailList.add(info);
                            });
                        });
                        //先放入
                        updateCloseDetailList.add(currentDetail);

                        CreateFulfillmentOrderDetailDTO detailReq = new CreateFulfillmentOrderDetailDTO();
                        detailReq.setSourceOrderLineNo(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString());
                        detailReq.setRefOrderNo(currentAllocateOrder.getCode());
                        detailReq.setRefOrderLineNo(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString());
                        detailReq.setMaterialCode(currentDetail.getScItemCode());
                        detailReq.setRefOrderLineNo(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString());
                        detailReq.setRefOrderCreateTime(currentAllocateOrder.getGmt_create() == null ? null :
                                DateFormatUtil.toString(currentAllocateOrder.getGmt_create(),"yyyy-MM-dd HH:mm:ss"));
                        detailReq.setProductionDate(currentDetail.getExpectedProduceDate() == null ? null :
                                DateFormatUtil.toString(currentDetail.getExpectedProduceDate(),"yyyy-MM-dd"));
                        detailReq.setSalesUnitCode(StringUtils.isBlank(currentDetail.getUnit()) ? "PC" : currentDetail.getUnit());
                        BigDecimal difference = currentConfirmQuantity.subtract(sumQuantity);
//                        detailReq.setSaleQuantity(difference);
                        if (Boolean.TRUE.equals(currentAllocateOrder.getReturnOrder())){
                            detailReq.setSaleQuantity(new BigDecimal(currentDetail.getQuantity().trim()));
                        }else {
                            detailReq.setSaleQuantity(new BigDecimal(currentDetail.getConfirmQuantity().trim()));
                        }
                        detailReq.setQuantity(difference);
                        detailReq.setShippingUnitCode(StringUtils.isBlank(currentDetail.getUnit()) ? "PC" : currentDetail.getUnit());
                        detailReq.setRemark(currentDetail.getRemarks());
                        detailReq.setClose(Boolean.TRUE.equals(currentDetail.getClose()) ? 1 : 0);
                        detailReq.setCloseReasonCode(currentDetail.getCloseCode());
                        detailReq.setCloseReason(currentDetail.getCloseReason());
                        Map<String,String> featuresMap = Maps.newHashMap();
                        if (StringUtils.isNotBlank(currentDetail.getOutAllocateOrderLineId())){
                            featuresMap.put(FeaturesKey.OUT_ALLOCATE_ORDER_LINE_ID,currentDetail.getOutAllocateOrderLineId());
                        }
                        if (StringUtils.isNotBlank(currentDetail.getBizFeatures())){
                            Map<String, String> detailBizFeatures = FeatureUtil.fromString(currentDetail.getBizFeatures());
                            if (StringUtils.isNotBlank(detailBizFeatures.get(FeaturesKey.BIZ_UNIT_RATIO))){
                                featuresMap.put(FeaturesKey.BIZ_UNIT_RATIO,detailBizFeatures.get(FeaturesKey.BIZ_UNIT_RATIO));
                                JSONObject bizFeaturesJsonObject = new JSONObject();
                                bizFeaturesJsonObject.put(FeaturesKey.BIZ_UNIT_RATIO,detailBizFeatures.get(FeaturesKey.BIZ_UNIT_RATIO));
                                detailReq.setBizFeatures(bizFeaturesJsonObject.toJSONString());
                            }
                        }
                        detailReq.setFeatures(FeatureUtil.toString(featuresMap));
                        if (AllocateOrderTypeEnum.FREIGHT_YARD_PICKUP.getType().equals(currentAllocateOrder.getType()) &&
                                Boolean.FALSE.equals(currentAllocateOrder.getReturnOrder())) {
                            detailReq.setBatchNo(FeatureUtil.fromString(currentDetail.getBizFeatures()).get("batchNo"));
                        }

                        createFulfillmentOrderDetailDTOList.add(detailReq);
                    }
                    continue;
                }
            }
            if (quantity.compareTo(BigDecimal.ZERO) <= 0){
                log.info("compare_confirm_quantity_less_than");
                continue;
            }

            CreateFulfillmentOrderDetailDTO detailReq = new CreateFulfillmentOrderDetailDTO();
            detailReq.setSourceOrderLineNo(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString());
            detailReq.setRefOrderNo(currentAllocateOrder.getCode());
            detailReq.setRefOrderLineNo(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString());
            detailReq.setMaterialCode(currentDetail.getScItemCode());
            detailReq.setRefOrderLineNo(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString());
            detailReq.setRefOrderCreateTime(currentAllocateOrder.getGmt_create() == null ? null :
                    DateFormatUtil.toString(currentAllocateOrder.getGmt_create(),"yyyy-MM-dd HH:mm:ss"));
            detailReq.setProductionDate(currentDetail.getExpectedProduceDate() == null ? null :
                    DateFormatUtil.toString(currentDetail.getExpectedProduceDate(),"yyyy-MM-dd"));
            detailReq.setSalesUnitCode(StringUtils.isBlank(currentDetail.getUnit()) ? "PC" : currentDetail.getUnit());
//            detailReq.setSaleQuantity(quantity);
            if (Boolean.TRUE.equals(currentAllocateOrder.getReturnOrder())){
                detailReq.setSaleQuantity(new BigDecimal(currentDetail.getQuantity().trim()));
            }else {
                detailReq.setSaleQuantity(new BigDecimal(currentDetail.getConfirmQuantity().trim()));
            }
            detailReq.setQuantity(quantity);
            detailReq.setShippingUnitCode(StringUtils.isBlank(currentDetail.getUnit()) ? "PC" : currentDetail.getUnit());
            detailReq.setRemark(currentDetail.getRemarks());
            detailReq.setClose(Boolean.TRUE.equals(currentDetail.getClose()) ? 1 : 0);
            detailReq.setCloseReasonCode(currentDetail.getCloseCode());
            detailReq.setCloseReason(currentDetail.getCloseReason());
            Map<String,String> featuresMap = Maps.newHashMap();
            if (StringUtils.isNotBlank(currentDetail.getOutAllocateOrderLineId())){
                featuresMap.put(FeaturesKey.OUT_ALLOCATE_ORDER_LINE_ID,currentDetail.getOutAllocateOrderLineId());
            }
            if (StringUtils.isNotBlank(currentDetail.getBizFeatures())){
                Map<String, String> detailBizFeatures = FeatureUtil.fromString(currentDetail.getBizFeatures());
                if (StringUtils.isNotBlank(detailBizFeatures.get(FeaturesKey.BIZ_UNIT_RATIO))){
                    featuresMap.put(FeaturesKey.BIZ_UNIT_RATIO,detailBizFeatures.get(FeaturesKey.BIZ_UNIT_RATIO));
                    JSONObject bizFeaturesJsonObject = new JSONObject();
                    bizFeaturesJsonObject.put(FeaturesKey.BIZ_UNIT_RATIO,detailBizFeatures.get(FeaturesKey.BIZ_UNIT_RATIO));
                    detailReq.setBizFeatures(bizFeaturesJsonObject.toJSONString());
                }
            }
            detailReq.setFeatures(FeatureUtil.toString(featuresMap));
            if (AllocateOrderTypeEnum.FREIGHT_YARD_PICKUP.getType().equals(currentAllocateOrder.getType()) &&
                    Boolean.FALSE.equals(currentAllocateOrder.getReturnOrder())) {
                detailReq.setBatchNo(FeatureUtil.fromString(currentDetail.getBizFeatures()).get("batchNo"));
            }
            detailReqList.add(detailReq);
        }
        return detailReqList;
    }

    /**
     * 获取履约单
     * @param sourceOrderNo 来源单号
     * @param fulfillmentDirectionType FulfillmentDirectionTypeEnum
     * @return 履约单
     */
    private List<FulfillmentGetRes> searchFulfillmentOrder(String sourceOrderNo, Integer fulfillmentDirectionType) {
        SearchFulfullmentOrderReq searchFulfullmentOrderReq = new SearchFulfullmentOrderReq();
        searchFulfullmentOrderReq.setSourceOrderNo(sourceOrderNo);
        searchFulfullmentOrderReq.setFulfillmentDirectionType(fulfillmentDirectionType);
        log.info("AllocateOrderSapSyncMessageServiceImpl_searchFulfillmentOrder_req:{}", JSON.toJSONString(searchFulfullmentOrderReq));
        com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result<List<FulfillmentGetRes>> searchFulfillmentOrder = fulfillmentOrderAbilityService.searchFulfullmentOrder(searchFulfullmentOrderReq);
        log.info("AllocateOrderSapSyncMessageServiceImpl_searchFulfillmentOrder_result:{}",JSON.toJSONString(searchFulfillmentOrder));
        if (CollectionUtils.isNotEmpty(searchFulfillmentOrder.getResult())) {
            return searchFulfillmentOrder.getResult();
        }
        return new ArrayList<>(0);
    }

    private List<WarehousingOrderDTO> filterForwardWmsOrderList(String bizOrderId, List<FulfillmentGetRes> fulfillmentGetResList){
        List<WarehousingOrderDTO> wmsOrderList = searchWarehousingOrderDTOS(bizOrderId);
        return Nullable.stream(wmsOrderList).filter(wms -> Nullable.stream(fulfillmentGetResList)
                .anyMatch(f -> Objects.equals(f.getFulfillmentOrderNo(),wms.getFulfillmentOrderId())
                && FulfillmentDirectionTypeEnum.FORWARD.getValue().equals(f.getFulfillmentDirectionType()))
        ).collect(Collectors.toList());
    }
    private List<WarehousingOrderDTO> searchWarehousingOrderDTOS(String bizOrderId){
        if (StringUtils.isBlank(bizOrderId)){
            return Lists.newArrayList();
        }
        WmsOrderQueryRequest wmsOrderQueryRequest = new WmsOrderQueryRequest();
        wmsOrderQueryRequest.setContainSubOrders(true);
        wmsOrderQueryRequest.setBizOrderId(bizOrderId);
        com.alibaba.cz.base.tool.result.Result<WarehousingOrdersQueryResponse> result = warehousingOrderReadService.queryWmsOrderByOtherOrder(wmsOrderQueryRequest);
        if (result != null && result.getResult() != null && CollectionUtils.isNotEmpty(result.getResult().getWarehousingOrders())){
            return result.getResult().getWarehousingOrders();
        }
        return Lists.newArrayList();
    }

    /**
     * 构建履约单主单
     * @param allocateOrder
     * @return
     */
    public CreateFulfillmentOrderReq buildCreateFulfillmentOrderReq(AllocateOrder allocateOrder){
        CreateFulfillmentOrderReq req = new CreateFulfillmentOrderReq();
        if (StringUtils.isNotBlank(allocateOrder.getFromSys())){
            req.setFromSys(allocateOrder.getFromSys());
        }else {
            req.setFromSys("APP_SAP");
        }
        req.setBusinessType(StringUtils.isNotBlank(allocateOrder.getBusinessType()) ? allocateOrder.getBusinessType() : "11");
        //TODO 业务单据编码
        req.setBusinessUnitCode("6000");
        req.setRequestNo(UUID.randomUUID().toString().replaceAll("-",""));
        //调拨单号
        req.setSourceOrderNo(allocateOrder.getCode());
        //退单:调拨退单出库,  否:调拨出库
        if (Boolean.TRUE.equals(allocateOrder.getReturnOrder())){
            req.setRefOrderType(OrderTypeEnum.ALLOCATE_RETURN_OUTBOUND.getValue());
        }else {
            req.setRefOrderType(OrderTypeEnum.ALLOCATE_OUTBOUND.getValue());
        }
        //调出仓和调入仓属于同一个物理仓（虚拟移库） 更正逻辑改为如果调拨单创建时履约类型为虚拟移库,则这里传递为虚拟移库
//        if (Objects.equals(allocateOrder.getShipWarehouseId(),allocateOrder.getReceiveWarehouseId())){
        if (com.epoch.app.crunifiedinventory.model.enums.FulfillmentTypeEnum.VIRTUAL_TRANSFER.getValue().toString().equals(allocateOrder.getFulfillmentTypeCode())){
            req.setFulfillmentType(FulfillmentTypeEnum.EXTERNALWAREHOUSE_FULFILLMENT.getValue());
        }else {
            req.setFulfillmentType(FulfillmentTypeEnum.BIGWAREHOUSE_FULFILLMENT.getValue());
        }
        req.setAutoSubmit(Boolean.TRUE);
        //枚举：：1=普通，100=优先
        req.setPriority(allocateOrder.getPriority() == null ? "1" : allocateOrder.getPriority().toString());
        req.setProductGroupCode(allocateOrder.getProductGroup());
        Map<String, CargoZoneSDO> cargoZoneSDOMap = this.getCargoZoneSDOMap(Arrays.asList(allocateOrder.getShipAreaId(), allocateOrder.getReceiveAreaId(), allocateOrder.getShipWarehouseId(), allocateOrder.getReceiveWarehouseId()).stream().filter(StringUtils::isNotBlank)
                .collect(Collectors.toList()));
        Map<String, CargoZoneSDO> codeZoneSDOMap = this.getCargoZoneSDOMapByCodes(Arrays.asList(allocateOrder.getTransferWarehouseId()).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()));
        String logicShippingWarehouseCode = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getShipAreaId())).map(CargoZoneSDO::getCode).orElse(null);
        String logicShippingWarehouseName = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getShipAreaId())).map(CargoZoneSDO::getName).orElse(null);
        String shippingWarehouseCode = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getShipWarehouseId())).map(CargoZoneSDO::getCode).orElse(null);
        String shippingWarehouseName = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getShipWarehouseId())).map(CargoZoneSDO::getName).orElse(null);
        String logicReceivingWarehouseCode = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId())).map(CargoZoneSDO::getCode).orElse(null);
        String logicReceivingWarehouseName = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId())).map(CargoZoneSDO::getName).orElse(null);
        String receivingWarehouseCode = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getReceiveWarehouseId())).map(CargoZoneSDO::getCode).orElse(null);
        String receivingWarehouseName = Optional.ofNullable(cargoZoneSDOMap.get(allocateOrder.getReceiveWarehouseId())).map(CargoZoneSDO::getName).orElse(null);
        String transferWarehouseName = Optional.ofNullable(codeZoneSDOMap.get(allocateOrder.getTransferWarehouseId())).map(CargoZoneSDO::getName).orElse(null);
        Map<String,String> features = Maps.newHashMap();
        features.put(FeaturesKey.OUT_ALLOCATE_ORDER_ID,allocateOrder.getOutAllocateOrderId());
        //创建货场提货单时的入库单号
        Map<String, String> allocateOrderBizFeatures = FeatureUtil.fromString(allocateOrder.getBizFeatures());
        features.put(FeaturesKey.ORIGIN_PLAN_WMS_ORDER_ID,allocateOrderBizFeatures.get(FeaturesKey.ORIGIN_PLAN_WMS_ORDER_ID));
        if (Boolean.TRUE.equals(allocateOrder.getReturnOrder())){
            req.setLogicReceivingWarehouseCode(logicShippingWarehouseCode);
            req.setLogicReceivingWarehouse(logicShippingWarehouseName);
            req.setReceivingWarehouseCode(shippingWarehouseCode);
            req.setReceivingWarehouse(shippingWarehouseName);
            features.put(FeaturesKey.TRANSFER_ORDER_TARGET_LOGIC_WAREHOUSE_CODE,logicShippingWarehouseCode);
            if (ToolUtil.isTrainOrSea(allocateOrder.getShipMethod())){
                req.setLogicShippingWarehouseCode(allocateOrder.getTransferWarehouseId());
                req.setLogicShippingWarehouse(transferWarehouseName);
            }else {
                req.setLogicShippingWarehouseCode(logicReceivingWarehouseCode);
                req.setLogicShippingWarehouse(logicReceivingWarehouseName);
                req.setShippingWarehouseCode(receivingWarehouseCode);
                req.setShippingWarehouse(receivingWarehouseName);
            }
            CargoZoneSDO cargoZoneSDO = cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId());
            if (cargoZoneSDO != null && cargoZoneSDO.getFeature() != null){
                req.setSoldToPartyCode(cargoZoneSDO.getFeature().get("sapInternalSalesBPCode"));
                req.setShipToPartyCode(cargoZoneSDO.getFeature().get("sapInternalDeliveryBPCode"));
            }
        }else {
            req.setLogicShippingWarehouseCode(logicShippingWarehouseCode);
            req.setLogicShippingWarehouse(logicShippingWarehouseName);
            req.setShippingWarehouseCode(shippingWarehouseCode);
            req.setShippingWarehouse(shippingWarehouseName);
            features.put(FeaturesKey.TRANSFER_ORDER_TARGET_LOGIC_WAREHOUSE_CODE,logicReceivingWarehouseCode);
            if (ToolUtil.isTrainOrSea(allocateOrder.getShipMethod())){
                req.setLogicReceivingWarehouseCode(allocateOrder.getTransferWarehouseId());
                req.setLogicReceivingWarehouse(transferWarehouseName);
//                CargoZoneSDO cargoZoneSDO = codeZoneSDOMap.get(allocateOrder.getTransferWarehouseId());
                CargoZoneSDO cargoZoneSDO = cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId());
                if (cargoZoneSDO != null && MapUtils.isNotEmpty(cargoZoneSDO.getFeature())){
                    req.setSoldToPartyCode(cargoZoneSDO.getFeature().get("sapInternalSalesBPCode"));
                    req.setShipToPartyCode(cargoZoneSDO.getFeature().get("sapInternalDeliveryBPCode"));
                }
            }else {
                req.setLogicReceivingWarehouseCode(logicReceivingWarehouseCode);
                req.setLogicReceivingWarehouse(logicReceivingWarehouseName);
                req.setReceivingWarehouseCode(receivingWarehouseCode);
                req.setReceivingWarehouse(receivingWarehouseName);
                //客户售达方编码 来自于仓库上的售达方编码
                CargoZoneSDO cargoZoneSDO = cargoZoneSDOMap.get(allocateOrder.getReceiveAreaId());
                if (cargoZoneSDO != null && MapUtils.isNotEmpty(cargoZoneSDO.getFeature())){
                    req.setSoldToPartyCode(cargoZoneSDO.getFeature().get("sapInternalSalesBPCode"));
                    req.setShipToPartyCode(cargoZoneSDO.getFeature().get("sapInternalDeliveryBPCode"));
                }
            }
        }
        Map<String, String> mainBizFeaturesMap = FeatureUtil.fromString(allocateOrder.getBizFeatures());
        if (StringUtils.isNotBlank(mainBizFeaturesMap.get(FeaturesKey.TRANSFER_OUT_BIZ_UNIT))){
            features.put(FeaturesKey.TRANSFER_OUT_BIZ_UNIT,mainBizFeaturesMap.get(FeaturesKey.TRANSFER_OUT_BIZ_UNIT));
        }
        if (StringUtils.isNotBlank(mainBizFeaturesMap.get(FeaturesKey.BIZ_UNIT))){
            features.put(FeaturesKey.BIZ_UNIT,mainBizFeaturesMap.get(FeaturesKey.BIZ_UNIT));
        }
        //可以后移
        if (MapUtils.isNotEmpty(features)){
            req.setFeatures(FeatureUtil.toString(features));
            req.setBizFeatures(JSONObject.toJSONString(features));
        }
        req.setProductGroupCode(StringUtils.isNotBlank(allocateOrder.getProductGroup()) ? allocateOrder.getProductGroup() : "11");
        req.setChannelCode("90");
        //6000?
        req.setSalesOrganizationCode("6000");
        //TODO 送达方 售达方 选择仓库上的, 待定
//            req.setShipToPartyCode();
//        req.setCreator(allocateOrder.getCreator());
        req.setExpectedDeliveryTime(Objects.isNull(allocateOrder.getExpectedDeliveryDate()) ? null :
                DateFormatUtil.toString(allocateOrder.getExpectedDeliveryDate(),DateFormatUtil.TIME_PATTERN));
        req.setShippingMethodCode(allocateOrder.getShipMethod() == null ? null : allocateOrder.getShipMethod().toString());
        req.setRemark(allocateOrder.getRemark());
        return req;
    }

    //TODO 联调临时用一下,后面再抽出来
    public Map<String,CargoZoneSDO> getCargoZoneSDOMap(List<String> idList){
        log.info("abc_request:{}",JSON.toJSONString(idList));
        Map<String,CargoZoneSDO> map = Maps.newHashMap();
        if (CollectionUtils.isEmpty(idList)){
            return map;
        }
        QueryCargoZoneRequest queryCargoZoneRequest = new QueryCargoZoneRequest();
        queryCargoZoneRequest.setWarehouseAreaIds(idList);
        queryCargoZoneRequest.setStart(0);
        queryCargoZoneRequest.setSize(idList.size());
        log.info("abcd_request:{}",JSON.toJSONString(queryCargoZoneRequest));
        com.alibaba.cz.base.tool.result.Result<ResultPager<List<CargoZoneSDO>>> resultPagerResult = cargoZoneQueryService.searchCargoZoneListByDB(queryCargoZoneRequest);
        log.info("abc_res:{}",JSON.toJSONString(resultPagerResult));
        Optional.ofNullable(resultPagerResult).map(com.alibaba.cz.base.tool.result.Result::getResult)
                .map(ResultPager::getContent).orElse(com.google.common.collect.Lists.newArrayList())
                .stream().forEach(cargoZoneSDO -> map.put(cargoZoneSDO.getId(),cargoZoneSDO));
        return map;
    }

    public Map<String,CargoZoneSDO> getCargoZoneSDOMapByCodes(List<String> codes){
        log.info("code_request:{}",JSON.toJSONString(codes));
        Map<String,CargoZoneSDO> map = Maps.newHashMap();
        if (CollectionUtils.isEmpty(codes)){
            return map;
        }
        QueryCargoZoneRequest queryCargoZoneRequest = new QueryCargoZoneRequest();
        queryCargoZoneRequest.setCodes(codes);
        queryCargoZoneRequest.setStart(0);
        queryCargoZoneRequest.setSize(codes.size());
        log.info("code_request:{}",JSON.toJSONString(queryCargoZoneRequest));
        com.alibaba.cz.base.tool.result.Result<ResultPager<List<CargoZoneSDO>>> resultPagerResult = cargoZoneQueryService.searchCargoZoneListByDB(queryCargoZoneRequest);
        log.info("code_res:{}",JSON.toJSONString(resultPagerResult));
        Optional.ofNullable(resultPagerResult).map(com.alibaba.cz.base.tool.result.Result::getResult)
                .map(ResultPager::getContent).orElse(com.google.common.collect.Lists.newArrayList())
                .stream().forEach(cargoZoneSDO -> map.put(cargoZoneSDO.getCode(),cargoZoneSDO));
        return map;
    }

    /**
     * 构建出更新履约单features的入参
     * @param req
     * @param res
     * @return
     */
    public UpdateFulfillmentOrderFeaturesReq buildUpdateFulfillmentOrderFeaturesReq(CreateFulfillmentOrderReq req,FulfillmentOrderResponse res){
        UpdateFulfillmentOrderFeaturesReq featuresReq = new UpdateFulfillmentOrderFeaturesReq();
        featuresReq.setFulfillmentOrderNo(res.getFulfillmentOrderNo());
        featuresReq.setFeatures(req.getFeatures());
        List<UpdateFulfillmentOrderDetailFeaturesReq> subList = Lists.newArrayList();
        req.getDetailList().forEach(detail -> {
            UpdateFulfillmentOrderDetailFeaturesReq detailFeaturesReq = new UpdateFulfillmentOrderDetailFeaturesReq();
            detailFeaturesReq.setSourceOrderLineNo(detail.getSourceOrderLineNo());
            detailFeaturesReq.setFeatures(detail.getFeatures());
            subList.add(detailFeaturesReq);
        });
        featuresReq.setDetailList(subList);
        return featuresReq;
    }


    /**
     * 新增一行调拨单时增加履约单
     * @param currentAllocateOrder
     * @param currentDetail
     * @param quantity
     * @return
     */
    private CreateFulfillmentOrderDetailDTO composeDetailReq(AllocateOrder currentAllocateOrder,AllocateOrderDetail currentDetail,BigDecimal quantity){
        CreateFulfillmentOrderDetailDTO detailReq = new CreateFulfillmentOrderDetailDTO();
        detailReq.setSourceOrderLineNo(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString());
        detailReq.setRefOrderNo(currentAllocateOrder.getCode());
        detailReq.setRefOrderLineNo(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString());
        detailReq.setMaterialCode(currentDetail.getScItemCode());
        detailReq.setRefOrderLineNo(currentDetail.getLineNo() == null ? null : currentDetail.getLineNo().toString());
        detailReq.setRefOrderCreateTime(currentAllocateOrder.getGmt_create() == null ? null :
                DateFormatUtil.toString(currentAllocateOrder.getGmt_create(),"yyyy-MM-dd HH:mm:ss"));
        detailReq.setProductionDate(currentDetail.getExpectedProduceDate() == null ? null :
                DateFormatUtil.toString(currentDetail.getExpectedProduceDate(),"yyyy-MM-dd"));
        detailReq.setSalesUnitCode(StringUtils.isBlank(currentDetail.getUnit()) ? "PC" : currentDetail.getUnit());
//        detailReq.setSaleQuantity(quantity);
        if (Boolean.TRUE.equals(currentAllocateOrder.getReturnOrder())){
            detailReq.setSaleQuantity(new BigDecimal(currentDetail.getQuantity().trim()));
        }else {
            detailReq.setSaleQuantity(new BigDecimal(currentDetail.getConfirmQuantity().trim()));
        }
        detailReq.setQuantity(quantity);
        detailReq.setShippingUnitCode(StringUtils.isBlank(currentDetail.getUnit()) ? "PC" : currentDetail.getUnit());
        detailReq.setRemark(currentDetail.getRemarks());
        detailReq.setClose(Boolean.TRUE.equals(currentDetail.getClose()) ? 1 : 0);
        detailReq.setCloseReasonCode(currentDetail.getCloseCode());
        detailReq.setCloseReason(currentDetail.getCloseReason());
        Map<String,String> featuresMap = Maps.newHashMap();
        if (StringUtils.isNotBlank(currentDetail.getOutAllocateOrderLineId())){
            featuresMap.put(FeaturesKey.OUT_ALLOCATE_ORDER_LINE_ID,currentDetail.getOutAllocateOrderLineId());
        }
        detailReq.setFeatures(FeatureUtil.toString(featuresMap));
        if (AllocateOrderTypeEnum.FREIGHT_YARD_PICKUP.getType().equals(currentAllocateOrder.getType()) &&
                Boolean.FALSE.equals(currentAllocateOrder.getReturnOrder())) {
            detailReq.setBatchNo(FeatureUtil.fromString(currentDetail.getBizFeatures()).get("batchNo"));
        }
        return detailReq;
    }

    /**
     * 调拨单由关闭变成打开
     * @param origin
     * @param current
     */
    private void closeToOpen(com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntity origin,
                             com.alibaba.citrus.cr.unified.inventory.model.AllocateOrderEntity current){
        if (!AllocateOrderTypeEnum.PLAN.getType().equals(current.getAllocateOrder().getType())) {
            return;
        }
        //找出之前是关闭的行,现在是打开的行
        List<AllocateOrderDetail> originCloseDetailList = Optional.ofNullable(origin).map(AllocateOrderEntity::getDetailList)
                .orElse(Lists.newArrayList())
                .stream().filter(detail -> Boolean.TRUE.equals(detail.getClose()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(originCloseDetailList)){
            return;
        }
        log.info("closeToOpen_originCloseDetailList:{}",JSON.toJSONString(originCloseDetailList));
        List<AllocateOrderDetail> currentOpenDetailList = Nullable.stream(current.getDetailList())
                .filter(detail -> !Boolean.TRUE.equals(detail.getClose()))
                .filter(detail -> originCloseDetailList.stream().anyMatch(originDetail -> Objects.equals(detail.getLineNo(), originDetail.getLineNo())))
                .collect(Collectors.toList());
        log.info("closeToOpen_currentOpenDetailList:{}",JSON.toJSONString(currentOpenDetailList));
        if (CollectionUtils.isNotEmpty(currentOpenDetailList)){
            //针对这些明细设置状态值为待发货
            currentOpenDetailList.forEach(detail -> {
                com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.UpdateStatusRequest updateStatusRequest =
                        com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.UpdateStatusRequest.builder()
                                .id(detail.getId())
                                .status(AllocateOrderStatus.Shipment_Processing.getValue()).build();
                allocateOrderDetailService.updateStatus(updateStatusRequest);
            });
            //然后再调用一下更新状态的方法试着将状态回推.
            UpdateStatusRequest updateStatusRequest = UpdateStatusRequest.builder().code(current.getAllocateOrder().getCode()).build();
            allocateOrderDomainService.updateStatus(updateStatusRequest);
        }
    }
}
